/* Copyright (c) 2022 Peigen.info. All rights reserved. */

package info.peigen.hotpot.common.core.enums;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.annotation.JSONCreator;
import com.alibaba.fastjson2.annotation.JSONType;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <b>(MeasuringUnit)</b>
 *
 * @author Peigen
 * @version 1.0.0
 * @since 2024/5/16
 */
@Getter
@NoArgsConstructor
@AllArgsConstructor
@JSONType(writeEnumAsJavaBean = true)
public enum MeasuringUnit implements Messageable {
    /** 为了对抗 Alibaba Java Coding 而存在的注释 */
    A01030100("平方米", "境外土地"),
    A01039900("平方米", "其他土地"),
    
    A01010100("平方米", "办公用房"),
    A01010201("平方米", "警察业务用房"),
    A01010202("平方米", "检察业务用房"),
    A01010203("平方米", "司法业务用房"),
    A01010204("平方米", "法院业务用房"),
    A01010205("平方米", "纪委监委业务用房"),
    A01010206("平方米", "税务业务用房"),
    A01010207("平方米", "审计业务用房"),
    A01010208("平方米", "海关业务用房"),
    A01010209("平方米", "水利业务用房"),
    A01010210("平方米", "应急救援业务用房"),
    A01010211("平方米", "教育用房"),
    A01010212("平方米", "医疗卫生用房"),
    A01010214("平方米", "文化用房"),
    A01010215("平方米", "新闻用房"),
    A01010216("平方米", "娱乐用房"),
    A01010217("平方米", "园林绿化用房"),
    A01010218("平方米", "体育用房"),
    A01010219("平方米", "工业生产用房"),
    A01010220("平方米", "市政公用设施用房"),
    A01010221("平方米", "铁路用房"),
    A01010222("平方米", "民航用房"),
    A01010223("平方米", "航运用房"),
    A01010224("平方米", "城市客运用房"),
    A01010225("平方米", "公路运输用房"),
    A01010226("平方米", "仓储用房"),
    A01010227("平方米", "发行库用房"),
    A01010228("平方米", "商业金融用房"),
    A01010229("平方米", "电讯信息用房"),
    A01010230("平方米", "监狱用房"),
    A01010231("平方米", "涉外用房"),
    A01010300("平方米", "宗教用房"),
    A01010400("平方米", "军事用房"),
    A01010500("平方米", "住宅"),
    A01019900("平方米", "其他房屋"),
    /** 不晓得啷格回事 */
    UNKNOWN("--", "不晓得啷格回事");

    /** 枚举值 */
    String code;

    /** 枚举描述 */
    String message;

    /**
     * 通过枚举<code>code</code>获得枚举
     *
     * @param code 枚举值
     *
     * @return MeasuringUnit
     */
    public static MeasuringUnit getByCode(String code) {
        return Stream.of(values())
                .filter(innerEnum -> StrUtil.equals(code, innerEnum.code()))
                .findFirst().orElse(UNKNOWN);
    }

    /**
     * 通过枚举<code>name</code>获得枚举
     *
     * @param name 枚举名
     *
     * @return MeasuringUnit
     */
    public static MeasuringUnit getByName(String name) {
        return Stream.of(values())
                .filter(innerEnum -> StrUtil.equalsIgnoreCase(name, innerEnum.name()))
                .findFirst().orElse(UNKNOWN);
    }

    @JSONCreator
    public static MeasuringUnit deserialize(String code, String message) {
        return Stream.of(values())
                .filter(innerEnum -> StrUtil.equals(code, innerEnum.code()))
                .findFirst().orElse(UNKNOWN);
    }

    /**
     * 获取全部枚举
     *
     * @return List<MeasuringUnit>
     */
    public static List<MeasuringUnit> getAllEnum() {
        return Lists.newArrayList(values());
    }

    /**
     * 获取全部枚举值
     *
     * @return List<String>
     */
    public static List<String> getAllEnumCode() {
        return getAllEnum().stream().map(MeasuringUnit::code).collect(Collectors.toList());
    }

    /**
     * 判断给定的枚举，是否在列表中
     *
     * @param values 列表
     *
     * @return Boolean
     */
    public boolean isInList(MeasuringUnit... values) {
        for (MeasuringUnit e : values) {
            if (this == e) {
                return true;
            }
        }
        return false;
    }

    /**
     * 通过code获取msg
     *
     * @param code 枚举值
     *
     * @return String
     */
    public static String getMsgByCode(String code) {
        return getByCode(code).message();
    }

    /**
     * 获取枚举code
     *
     * @param innerEnum 枚举
     *
     * @return code
     */
    public static String getCode(MeasuringUnit innerEnum) {
        return Optional.ofNullable(innerEnum).map(MeasuringUnit::code).orElse(UNKNOWN.code());
    }

    /**
     * map
     *
     * @return Map
     */
    public static Map<String, String> maps() {
        return Stream.of(values()).collect(Collectors.toMap(MeasuringUnit::code, MeasuringUnit::message));
    }

    /**
     * 该方法是为了避免NPE，安全获取枚举中的字段值
     */
    public static <T> T safeGet(MeasuringUnit enumValue, Function<MeasuringUnit, T> mapper, T defaultValue) {
        return Objects.isNull(enumValue) ? defaultValue : mapper.apply(enumValue);
    }

    /**
     * 该方法是为了避免NPE，安全获取枚举中的字段值，默认返回值是null
     */
    public static <T> T safeGet(MeasuringUnit enumValue, Function<MeasuringUnit, T> mapper) {
        return safeGet(enumValue, mapper, null);
    }

    /**
     * 该方法是为了避免NPE，安全获取枚举中的code值，默认返回值是null
     */
    public static String safeGetCode(MeasuringUnit enumValue) {
        return safeGet(enumValue, Messageable::code, null);
    }

    /**
     * @return Returns the code.
     */
    @Override
    public String code() {
        return code;
    }

    /**
     * @return Returns the message.
     */
    @Override
    public String message() {
        return message;
    }
}